#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "list.h"

int listhead_init(list_t **mylist, int size)
{
	list_t *me = NULL;

	me = malloc(sizeof(list_t));
	if (NULL == me)
		return -1;
	me->size = size;
	me->node.next = NULL;
	me->node.data = NULL; // 不用的

	*mylist = me;
	return 0;
}

// 开辟一个新的节点
static struct node_st *__alloc_node(int size, const void *data)
{
	struct node_st *new_node;

	new_node = malloc(sizeof(struct node_st));
	if (NULL == new_node)
		return NULL;
	new_node->data = malloc(size);
	if (NULL == new_node->data) {
		free(new_node);
		new_node = NULL;
		return NULL;
	}
	memcpy(new_node->data, data, size);
	new_node->next = NULL;

	return new_node;
}

int list_empty(const list_t *mylist)
{
	return mylist->node.next == NULL;
}

int list_insert(list_t *mylist, const void *data)
{
	// 头插
	struct node_st *n = __alloc_node(mylist->size, data);
	if (NULL == n)
		return -1;
	n->next = mylist->node.next;
	mylist->node.next = n;

	return 0;
}

int list_insert_tail(list_t *mylist, const void *data)
{
	struct node_st *pos;
	struct node_st *n = __alloc_node(mylist->size, data);
	if (NULL == n)
		return -1;
	if (list_empty(mylist)) {
		pos = &mylist->node;
	} else {
		for (pos = mylist->node.next; pos->next != NULL; pos = pos->next) {
			;
		}
	}
	pos->next = n;

	return 0;
}

static struct node_st *__prev_node(const list_t *mylist, const void *key, cmp_t cmp)
{
	struct node_st *prev = NULL;

	// 找到key匹配节点的前驱
	for (prev = (struct node_st *)&mylist->node; prev->next != NULL; prev = prev->next)	{
		if (0 == cmp(prev->next->data, key))
			return prev;
	}

	return NULL;
}

void *list_find(const list_t *mylist, const void *key, cmp_t cmp)
{
	struct node_st *prev;

	prev = __prev_node(mylist, key, cmp);
	if (NULL == prev)
		return NULL;
	return prev->next->data;
}

int list_delete(list_t *mylist, const void *key, cmp_t cmp)
{
	struct node_st *prev, *del;

	prev = __prev_node(mylist, key, cmp);
	if (NULL == prev)
		return -1;
	del = prev->next;
	prev->next = del->next;
	del->next = NULL;
	free(del->data);
	del->data = NULL;
	free(del);
	del = NULL;

	return 0;
}

void list_traval(const list_t *mylist, pri_t pri)
{
	struct node_st *cur = NULL;

	for (cur = mylist->node.next; cur != NULL; cur = cur->next) {
		pri(cur->data);
	}
}

static int __always_cmp(const void *data, const void *key)
{
	return 0;
}

void list_destroy(list_t **mylist)
{
	while (!list_empty(*mylist)) {
		list_delete(*mylist, NULL, __always_cmp);
	}
	free(*mylist);
	*mylist = NULL;
}



